Skip to content

KFLUXINFRA-4167: Create a staging ArgoCD instance for infra-deployments#532

Open
enkeefe00 wants to merge 1 commit into
redhat-appstudio:mainfrom
enkeefe00:create-infra-deployments-argocds
Open

KFLUXINFRA-4167: Create a staging ArgoCD instance for infra-deployments#532
enkeefe00 wants to merge 1 commit into
redhat-appstudio:mainfrom
enkeefe00:create-infra-deployments-argocds

Conversation

@enkeefe00

@enkeefe00 enkeefe00 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Use GitOps to deploy a staging ArgoCD instance for infra-deployments

@enkeefe00 enkeefe00 self-assigned this Jul 2, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

@enkeefe00: This pull request references KFLUXINFRA-4167 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Use GitOps to deploy ArgoCD instances for infra-deployments

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot requested review from arewm and glevi-rh July 2, 2026 16:29
@openshift-ci

openshift-ci Bot commented Jul 2, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: enkeefe00

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved label Jul 2, 2026
Comment thread argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml Outdated
@qodo-for-redhat-appstudio

Copy link
Copy Markdown

PR Summary by Qodo

Add GitOps-managed ArgoCD instance for infra-deployments (staging/prod)

✨ Enhancement ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add an ApplicationSet to deploy the infra-deployments ArgoCD instance via GitOps.
• Introduce a new component with base ArgoCD + RBAC and env-specific overlays.
• Provision environment credentials via ExternalSecrets and allow access to the Vault store.
Diagram

graph TD
  Dev["infra-common-deployments repo"] --> AppSet["ApplicationSet: infra instance"] --> App["ArgoCD Application"] --> Kust["Kustomize overlays"] --> ArgoCR["ArgoCD CR + RBAC"] --> Sync["Manages infra-deployments"]
  Allow["ClusterSecretStore allowlist"] --> Vault[("appsre-stonesoup-vault")]
  Vault --> ExtSec["ExternalSecrets"] --> ArgoCR
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Reuse an existing ArgoCD control-plane instance
  • ➕ Fewer operators/instances to maintain and patch
  • ➕ Avoids duplicating RBAC/resource settings across instances
  • ➖ Higher blast radius if misconfigured (shared ArgoCD)
  • ➖ Harder to isolate infra-deployments-specific RBAC and credentials
2. Deploy ArgoCD instance via Helm (instead of raw manifests + Kustomize)
  • ➕ Versioned chart values can be easier to diff/upgrade
  • ➕ Potentially less custom YAML to maintain
  • ➖ Adds chart dependency/templating complexity
  • ➖ May still require custom overlays/patches for operator-specific CR fields
3. Manual/imperative provisioning (bootstrap once)
  • ➕ Fast initial setup
  • ➕ Less GitOps wiring up front
  • ➖ Not reproducible/auditable long-term
  • ➖ Drift risk; contradicts GitOps goal stated by the PR

Recommendation: The PR’s GitOps-first approach (ApplicationSet + Kustomize overlays) is the best fit for repeatable multi-environment ArgoCD instance provisioning. The main thing to validate in review is correctness of wiring (ApplicationSet source path/environment values and destination namespace) and that the aggregated ClusterRole scope is intentionally broad for the components this instance will manage.

Files changed (29) +924 / -0

Documentation (1) +3 / -0
README.mdDocument purpose of the infra-deployments ArgoCD instance +3/-0

Document purpose of the infra-deployments ArgoCD instance

• Documents that this component deploys an ArgoCD instance intended to manage infra-deployments, initially for universal components/ring deployments migration.

components/argocd-infra-instance/README.md

Other (28) +921 / -0
appset.yamlAdd ApplicationSet to bootstrap infra-deployments ArgoCD instance +36/-0

Add ApplicationSet to bootstrap infra-deployments ArgoCD instance

• Introduces an ApplicationSet that generates an ArgoCD Application per cluster. The template points to the new component path and enables automated sync with prune/self-heal and infinite retries.

argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml

kustomization.yamlRegister infra instance ApplicationSet resources +5/-0

Register infra instance ApplicationSet resources

• Adds a kustomization that includes the new ApplicationSet manifest as a resource.

argo-cd-apps/base/internal/argocd-infra-instance/kustomization.yaml

OWNERSDefine component ownership for infra ArgoCD instance +7/-0

Define component ownership for infra ArgoCD instance

• Adds OWNERS metadata assigning approvers and reviewers to the konflux-infra-team.

components/argocd-infra-instance/OWNERS

argocd.yamlAdd ArgoCD Operator CR for argocd-infra-deployments +261/-0

Add ArgoCD Operator CR for argocd-infra-deployments

• Defines an ArgoCD custom resource with resource sizing, SSO via OpenShift OAuth (Dex), sync/diff customizations, and health checks. Configures route exposure and RBAC policy bindings for various Konflux groups.

components/argocd-infra-instance/base/argocd.yaml

clusterrole.yamlAdd aggregated ClusterRole for infra-deployments ArgoCD permissions +249/-0

Add aggregated ClusterRole for infra-deployments ArgoCD permissions

• Creates a cluster-scoped role labeled for aggregation to the ArgoCD controller. Grants broad permissions across core resources and many operator/API groups needed for infra management.

components/argocd-infra-instance/base/clusterrole.yaml

kustomization.yamlBase kustomization for ArgoCD instance + RBAC + namespace +7/-0

Base kustomization for ArgoCD instance + RBAC + namespace

• Defines the base resource set for the component: ArgoCD CR, aggregated ClusterRole, and namespace manifest.

components/argocd-infra-instance/base/kustomization.yaml

ns.yamlCreate namespace for argocd-infra-deployments +8/-0

Create namespace for argocd-infra-deployments

• Adds a Namespace manifest with labels identifying the ArgoCD instance and its association to konflux-common.

components/argocd-infra-instance/base/ns.yaml

kustomization.yamlProduction ExternalSecrets kustomization for cluster credentials +12/-0

Production ExternalSecrets kustomization for cluster credentials

• Lists production ExternalSecret resources to materialize per-cluster secrets from Vault for the ArgoCD instance.

components/argocd-infra-instance/internal-production/external-secrets/kustomization.yaml

ocp-p01-es.yamlProduction ExternalSecret for ocp-p01 +21/-0

Production ExternalSecret for ocp-p01

• Adds an ExternalSecret that extracts ocp-p01 credentials from Vault into a Kubernetes Secret, with ArgoCD sync options to skip dry-run on missing CRDs.

components/argocd-infra-instance/internal-production/external-secrets/ocp-p01-es.yaml

osp-p01-es.yamlProduction ExternalSecret for osp-p01 +21/-0

Production ExternalSecret for osp-p01

• Adds an ExternalSecret that extracts osp-p01 credentials from a terraform-generated Vault path into a Kubernetes Secret.

components/argocd-infra-instance/internal-production/external-secrets/osp-p01-es.yaml

prd-es01.yamlProduction ExternalSecret for prd-es01 +21/-0

Production ExternalSecret for prd-es01

• Adds an ExternalSecret to populate the prd-es01 secret from Vault with a 1h refresh interval.

components/argocd-infra-instance/internal-production/external-secrets/prd-es01.yaml

prd-p01-es.yamlProduction ExternalSecret for prd-p01 +21/-0

Production ExternalSecret for prd-p01

• Adds an ExternalSecret to populate the prd-p01 secret from Vault.

components/argocd-infra-instance/internal-production/external-secrets/prd-p01-es.yaml

prd-p02-es.yamlProduction ExternalSecret for prd-p02 +21/-0

Production ExternalSecret for prd-p02

• Adds an ExternalSecret to populate the prd-p02 secret from Vault.

components/argocd-infra-instance/internal-production/external-secrets/prd-p02-es.yaml

prd-rh01-es.yamlProduction ExternalSecret for prd-rh01 +21/-0

Production ExternalSecret for prd-rh01

• Adds an ExternalSecret to populate the prd-rh01 secret from Vault.

components/argocd-infra-instance/internal-production/external-secrets/prd-rh01-es.yaml

prd-rh02-es.yamlProduction ExternalSecret for prd-rh02 +21/-0

Production ExternalSecret for prd-rh02

• Adds an ExternalSecret to populate the prd-rh02 secret from Vault.

components/argocd-infra-instance/internal-production/external-secrets/prd-rh02-es.yaml

prd-rh03-es.yamlProduction ExternalSecret for prd-rh03 +21/-0

Production ExternalSecret for prd-rh03

• Adds an ExternalSecret to populate the prd-rh03 secret from a terraform-generated Vault path.

components/argocd-infra-instance/internal-production/external-secrets/prd-rh03-es.yaml

rhel-p01-es.yamlProduction ExternalSecret for rhel-p01 +21/-0

Production ExternalSecret for rhel-p01

• Adds an ExternalSecret to populate the rhel-p01 secret from a terraform-generated Vault path.

components/argocd-infra-instance/internal-production/external-secrets/rhel-p01-es.yaml

kustomization.yamlProduction overlay: base + ExternalSecrets + env patches +19/-0

Production overlay: base + ExternalSecrets + env patches

• Defines the production overlay, adding external-secrets and patching the ArgoCD/Namespace metadata to production-specific name/namespace.

components/argocd-infra-instance/internal-production/kustomization.yaml

argocd-environment-patches.yamlPatch ArgoCD CR name/namespace for production +8/-0

Patch ArgoCD CR name/namespace for production

• Replaces ArgoCD CR metadata name and namespace to use the production suffix.

components/argocd-infra-instance/internal-production/patches/argocd-environment-patches.yaml

namespace-environment-patches.yamlPatch Namespace name/labels for production +12/-0

Patch Namespace name/labels for production

• Replaces the namespace name and selected app labels to production-specific values.

components/argocd-infra-instance/internal-production/patches/namespace-environment-patches.yaml

kustomization.yamlStaging ExternalSecrets kustomization for cluster credentials +6/-0

Staging ExternalSecrets kustomization for cluster credentials

• Lists staging ExternalSecret resources to materialize per-cluster secrets from Vault.

components/argocd-infra-instance/internal-staging/external-secrets/kustomization.yaml

stg-es01-es.yamlStaging ExternalSecret for stg-es01 +21/-0

Staging ExternalSecret for stg-es01

• Adds an ExternalSecret that extracts stg-es01 credentials from Vault into a Kubernetes Secret.

components/argocd-infra-instance/internal-staging/external-secrets/stg-es01-es.yaml

stg-p01-es.yamlStaging ExternalSecret for stg-p01 +21/-0

Staging ExternalSecret for stg-p01

• Adds an ExternalSecret that extracts stg-p01 credentials from Vault into a Kubernetes Secret.

components/argocd-infra-instance/internal-staging/external-secrets/stg-p01-es.yaml

stg-rh01-es.yamlStaging ExternalSecret for stg-rh01 +21/-0

Staging ExternalSecret for stg-rh01

• Adds an ExternalSecret that extracts stg-rh01 credentials from Vault into a Kubernetes Secret.

components/argocd-infra-instance/internal-staging/external-secrets/stg-rh01-es.yaml

kustomization.yamlStaging overlay: base + ExternalSecrets + env patches +18/-0

Staging overlay: base + ExternalSecrets + env patches

• Defines the staging overlay, adding external-secrets and patching the ArgoCD/Namespace metadata to staging-specific name/namespace.

components/argocd-infra-instance/internal-staging/kustomization.yaml

argocd-environment-patches.yamlPatch ArgoCD CR name/namespace for staging +8/-0

Patch ArgoCD CR name/namespace for staging

• Replaces ArgoCD CR metadata name and namespace to use the staging suffix.

components/argocd-infra-instance/internal-staging/patches/argocd-environment-patches.yaml

namespace-environment-patches.yamlPatch Namespace name/labels for staging +12/-0

Patch Namespace name/labels for staging

• Replaces the namespace name and selected app labels to staging-specific values.

components/argocd-infra-instance/internal-staging/patches/namespace-environment-patches.yaml

appsre-stonesoup-vault-secret-store.yamlAllow infra-deployments ArgoCD instance to use Vault secret store +1/-0

Allow infra-deployments ArgoCD instance to use Vault secret store

• Adds argocd-infra-deployments to the allowlist for the appsre-stonesoup-vault ClusterSecretStore.

components/cluster-secret-store/base/appsre-stonesoup-vault-secret-store.yaml

@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch 4 times, most recently from 5c65f04 to 3b01561 Compare July 2, 2026 16:48
@enkeefe00

Copy link
Copy Markdown
Collaborator Author

/agentic_review

@enkeefe00 enkeefe00 requested a review from hugares July 2, 2026 16:48
@qodo-for-redhat-appstudio

qodo-for-redhat-appstudio Bot commented Jul 2, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (4) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 5 rules

Grey Divider


Action required

1. Prod Vault key in staging ✓ Resolved 🐞 Bug ⛨ Security
Description
The internal-staging ExternalSecret redhat-appstudio-externalsecret extracts from a
production/.../kflux-c-prd-i01/... Vault key, causing the staging ArgoCD instance to source
production-scoped GitHub repo credentials. This breaks staging/prod isolation and can grant staging
unintended production access (or fail if the prod secret format differs).
Code

components/argocd-infra-instance/internal-staging/external-secrets/redhat-appstudio-es.yaml[R10-16]

+spec:
+  dataFrom:
+    - extract:
+        conversionStrategy: Default
+        decodingStrategy: None
+        key: production/infrastructure/github-argocd/kflux-c-prd-i01/redhat-appstudio
+  refreshInterval: 1h
Relevance

⭐⭐⭐ High

PR #364 uses staging Vault path for internal-staging ArgoCD repo creds; production path in staging
is inconsistent/unsafe.

PR-#364
PR-#62
PR-#331

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new internal-staging ExternalSecret references a production Vault path
(production/.../kflux-c-prd-i01/...), while an existing internal-staging repo-creds ExternalSecret
for the same secret uses a staging Vault path (staging/.../kflux-c-stg-i01/...). This
inconsistency demonstrates the staging/prod mixup introduced by the PR.

components/argocd-infra-instance/internal-staging/external-secrets/redhat-appstudio-es.yaml[10-16]
components/argocd-repo-secrets/internal-staging/redhat-appstudio-externalsecret.yaml[10-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`components/argocd-infra-instance/internal-staging/external-secrets/redhat-appstudio-es.yaml` is an internal-staging manifest but it extracts secret data from a production Vault path (`production/infrastructure/.../kflux-c-prd-i01/...`). This will make the staging ArgoCD instance consume production credentials.

### Issue Context
There is already an existing staging repo-creds ExternalSecret in `components/argocd-repo-secrets/internal-staging/` that uses the corresponding `staging/infrastructure/.../kflux-c-stg-i01/...` Vault path for `redhat-appstudio`.

### Fix Focus Areas
- components/argocd-infra-instance/internal-staging/external-secrets/redhat-appstudio-es.yaml[10-16]
- components/argocd-repo-secrets/internal-staging/redhat-appstudio-externalsecret.yaml[10-16]

### Suggested change
Update the `spec.dataFrom[0].extract.key` in the new internal-staging ExternalSecret to the correct **staging** Vault key (likely matching the existing staging repo-creds secret: `staging/infrastructure/github-argocd/kflux-c-stg-i01/redhat-appstudio`), or otherwise to the intended staging credential location.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Missing prod overlay path 🐞 Bug ≡ Correctness
Description
The internal-production ArgoCD overlay forces values.environment=internal-production for all
ApplicationSets, so this new ApplicationSet will generate Applications whose source.path resolves
to components/argocd-infra-instance/internal-production, but this component only provides an
internal-staging overlay. In internal-production this will cause render/sync failures for the
generated Applications (invalid/missing source path).
Code

argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[R8-21]

+    - clusters:
+        values:
+          sourceRoot: components/argocd-infra-instance
+          environment: ""
+          clusterName: ""
+  template:
+    metadata:
+      name: argocd-infra-deployments-instance-{{nameNormalized}}
+    spec:
+      project: default
+      source:
+        path: '{{values.sourceRoot}}/{{values.environment}}'
+        repoURL: https://github.com/redhat-appstudio/infra-common-deployments.git
+        targetRevision: main
Relevance

⭐⭐⭐ High

Team previously fixed env→path mismatches in ApplicationSets (added env mapping/templating) to avoid
sync failures (PR284, PR14).

PR-#284
PR-#14

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new ApplicationSet computes its render path from values.environment, while the
internal-production overlay globally replaces that environment value to internal-production,
making the effective source.path point at a production overlay directory for this component.

argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[8-24]
argo-cd-apps/overlays/internal-production/environment-patch.yaml[1-4]
components/argocd-infra-instance/internal-staging/kustomization.yaml[1-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The ApplicationSet’s `source.path` depends on `values.environment`, and the internal-production Argo CD overlay patches all ApplicationSets to use `internal-production`. This makes the new ArgoCD infra instance Application(s) point to `components/argocd-infra-instance/internal-production`, but that overlay directory doesn’t exist in this component, so internal-production sync/render will fail.

### Issue Context
- The ApplicationSet source path is `{{values.sourceRoot}}/{{values.environment}}`.
- `argo-cd-apps/overlays/internal-production/environment-patch.yaml` replaces `/spec/generators/0/clusters/values/environment` with `internal-production` for all ApplicationSets.

### Fix Focus Areas
- components/argocd-infra-instance/internal-production/**[1-200]
- argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[8-21]

### Suggested fix
Create `components/argocd-infra-instance/internal-production/` with a `kustomization.yaml` and required patches/resources (mirroring internal-staging where appropriate), so `components/argocd-infra-instance/internal-production` is a valid render target in internal-production.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. ExternalSecrets land wrong namespace ✓ Resolved 🐞 Bug ≡ Correctness
Description
The ApplicationSet sets destination.namespace: argocd-infra-instance, but this component’s staging
overlay renames the ArgoCD/Namespace to argocd-infra-deployments-staging; since the ExternalSecret
manifests omit metadata.namespace and the overlay doesn’t set a kustomize namespace, those
ExternalSecrets will be created in argocd-infra-instance instead of the instance namespace. This
makes the overlay internally inconsistent (ArgoCD instance in one namespace; its
ExternalSecrets/Secrets in another).
Code

argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[R22-24]

+      destination:
+        namespace: argocd-infra-instance
+        name: in-cluster
Relevance

⭐⭐⭐ High

Repo has fixed ExternalSecrets namespace ambiguity by adding explicit metadata.namespace (PR102);
likely accept namespace consistency fix.

PR-#102

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The ApplicationSet’s destination namespace is argocd-infra-instance, while the component’s staging
overlay explicitly moves the ArgoCD/Namespace to argocd-infra-deployments-staging; the
ExternalSecret YAMLs omit namespace and the overlay kustomization does not set a namespace
transformer, so those ExternalSecrets will not follow the intended instance namespace.

argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[22-30]
components/argocd-infra-instance/base/argocd.yaml[1-6]
components/argocd-infra-instance/base/ns.yaml[1-8]
components/argocd-infra-instance/internal-staging/patches/argocd-namespace-patch.yaml[1-3]
components/argocd-infra-instance/internal-staging/kustomization.yaml[1-8]
components/argocd-infra-instance/internal-staging/external-secrets/stg-es01-es.yaml[1-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The ApplicationSet’s `destination.namespace` is `argocd-infra-instance`, but the component overlay patches the ArgoCD instance/Namespace to `argocd-infra-deployments-staging`. The ExternalSecret manifests do not specify `metadata.namespace`, and the staging kustomization does not set `namespace: ...`, so the ExternalSecrets will be applied into the Application destination namespace rather than the ArgoCD instance namespace.

### Issue Context
The staging overlay clearly intends the instance namespace to be `argocd-infra-deployments-staging` (patches rename the Namespace and ArgoCD metadata.namespace).

### Fix Focus Areas
- argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[22-30]
- components/argocd-infra-instance/internal-staging/kustomization.yaml[1-23]
- components/argocd-infra-instance/internal-staging/external-secrets/stg-es01-es.yaml[1-21]
- components/argocd-infra-instance/internal-staging/patches/argocd-namespace-patch.yaml[1-3]

### Suggested fix
Do one of the following (pick one consistent approach):
1) Patch this ApplicationSet per-environment to set `spec.template.spec.destination.namespace` to the actual instance namespace (e.g., `argocd-infra-deployments-staging` in internal-staging, and the corresponding production namespace in internal-production), OR
2) Set `namespace: argocd-infra-deployments-staging` in `components/argocd-infra-instance/internal-staging/kustomization.yaml` so namespaced resources (including ExternalSecrets) consistently land in the intended namespace, and also update the ApplicationSet destination namespace to match.

After the change, ensure ExternalSecrets and the ArgoCD CR are rendered into the same namespace for each environment.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (8)
4. AppSet not included ✓ Resolved 🐞 Bug ≡ Correctness
Description
The PR adds argo-cd-apps/base/internal/argocd-infra-instance, but
argo-cd-apps/base/internal/kustomization.yaml does not include it in resources, so internal
overlays that consume ../../base/internal will never render/apply this new ApplicationSet.
Code

argo-cd-apps/base/internal/argocd-infra-instance/kustomization.yaml[R1-5]

+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+  - appset.yaml
Relevance

⭐⭐⭐ High

Missing kustomize resource inclusions have been fixed/accepted before (re-add omitted resource) in
PR #354.

PR-#354

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The internal overlays include ../../base/internal, but that base kustomization’s resources list
omits the newly-added argocd-infra-instance directory, so its appset.yaml cannot be
rendered/applied.

argo-cd-apps/overlays/internal-staging/kustomization.yaml[4-9]
argo-cd-apps/base/internal/kustomization.yaml[4-16]
argo-cd-apps/base/internal/argocd-infra-instance/kustomization.yaml[1-5]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
A new ApplicationSet base (`argo-cd-apps/base/internal/argocd-infra-instance`) was added, but it is not referenced by `argo-cd-apps/base/internal/kustomization.yaml`. As a result, the internal overlays that include `../../base/internal` will not apply this ApplicationSet, so the new ArgoCD instance rollout is effectively a no-op.

### Issue Context
- Internal overlays render `../../base/internal`.
- `../../base/internal/kustomization.yaml` enumerates internal apps explicitly.
- The new `argocd-infra-instance` directory is missing from that list.

### Fix Focus Areas
- argo-cd-apps/base/internal/kustomization.yaml[4-16]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Overlay patches won't apply 🐞 Bug ≡ Correctness
Description
The environment patch files are not valid JSON6902 patch lists (they are multiple YAML documents,
not a single sequence), and the Namespace patch target uses group: v1 which cannot match core
Namespace resources; as a result, the environment-specific renames/namespaces will not be applied.
Code

components/argocd-infra-instance/internal-staging/patches/argocd-environment-patches.yaml[R1-8]

+---
+op: replace
+path: /metadata/namespace
+value: argocd-infra-deployments-staging
+---
+op: replace
+path: /metadata/name
+value: argocd-infra-deployments-staging
Relevance

⭐⭐⭐ High

Team has accepted multiple kustomize overlay/patch correctness fixes to prevent build/sync failures
(PR #4, PR #393).

PR-#4
PR-#393

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Kustomize JSON6902 expects a sequence of patch ops; the overlay patches are written as separate YAML
documents with no list items. Also, the overlay tries to target Namespace using group: v1, while a
working Namespace patch example in-repo omits group entirely for core resources.

components/argocd-infra-instance/internal-staging/patches/argocd-environment-patches.yaml[1-8]
components/argocd-infra-instance/internal-staging/kustomization.yaml[14-18]
components/kueue/internal-production/tekton-kueue/controller-patch.yaml[1-8]
components/kueue/internal-staging/tekton-kueue/kustomization.yaml[40-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The patch files under `components/argocd-infra-instance/internal-*/patches/` are not in a valid JSON6902 format (must be a YAML/JSON array of ops). Additionally, the kustomization targets `Namespace` with `group: v1`, but core resources have an empty API group, so the patch selector will not match.

## Issue Context
Valid JSON6902 patches in this repo are expressed as a YAML list (each op is a `- op: ...` item).

## Fix Focus Areas
- components/argocd-infra-instance/internal-staging/patches/argocd-environment-patches.yaml[1-8]
- components/argocd-infra-instance/internal-staging/patches/namespace-environment-patches.yaml[1-12]
- components/argocd-infra-instance/internal-staging/kustomization.yaml[14-18]
- components/argocd-infra-instance/internal-production/patches/argocd-environment-patches.yaml[1-8]
- components/argocd-infra-instance/internal-production/patches/namespace-environment-patches.yaml[1-12]
- components/argocd-infra-instance/internal-production/kustomization.yaml[15-19]

## Proposed fix
1) Rewrite each patch file as a single YAML list, e.g.:
```yaml
- op: replace
 path: /metadata/namespace
 value: ...
- op: replace
 path: /metadata/name
 value: ...
```
2) For the Namespace patch target, either omit `group` entirely or set it to empty (`group: ""`). Keep `version: v1`.
3) (Optional sanity) The internal-production overlay also sets `namespace: argocd-infra-deployments` while patches try to set `/metadata/namespace` to `...-production`; pick a single source of truth for the namespace to avoid conflicting transforms.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Missing staging ExternalSecret file ✓ Resolved 🐞 Bug ≡ Correctness
Description
components/argocd-infra-instance/internal-staging/external-secrets/kustomization.yaml references
stg-p01.yaml, but the actual file added is stg-p01-es.yaml, which breaks the staging overlay
build.
Code

components/argocd-infra-instance/internal-staging/external-secrets/kustomization.yaml[R1-6]

+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+  - stg-rh01-es.yaml
+  - stg-es01-es.yaml
+  - stg-p01.yaml
Relevance

⭐⭐⭐ High

Similar to prior accepted fixes where missing/incorrect kustomization resources broke deployments
(PR #347).

PR-#347

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The kustomization resource list contains stg-p01.yaml, but the only corresponding manifest present
is stg-p01-es.yaml.

components/argocd-infra-instance/internal-staging/external-secrets/kustomization.yaml[1-6]
components/argocd-infra-instance/internal-staging/external-secrets/stg-p01-es.yaml[1-4]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The staging external-secrets kustomization references a non-existent resource file (`stg-p01.yaml`).

## Issue Context
The file present in the directory is `stg-p01-es.yaml`.

## Fix Focus Areas
- components/argocd-infra-instance/internal-staging/external-secrets/kustomization.yaml[1-6]

## Proposed fix
Update the resource entry to `stg-p01-es.yaml` (or rename the file to match the current reference).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. ExternalSecrets namespace not allowed 🐞 Bug ☼ Reliability
Description
ExternalSecrets in this component reference ClusterSecretStore/appsre-stonesoup-vault, but the
store allowlist only adds argocd-infra-deployments and not the effective namespaces implied by the
staging destination (argocd-infra-instance) or the intended env namespaces
(argocd-infra-deployments-staging/production), which will prevent secret reconciliation.
Code

components/cluster-secret-store/base/appsre-stonesoup-vault-secret-store.yaml[R39-42]

        - konflux-devprod-poc
        - kargo-infra-common
        - kargo-shard-staging
+        - argocd-infra-deployments
Relevance

⭐⭐⭐ High

Namespace allowlist mismatch for ClusterSecretStore was explicitly accepted/fixed before (PR #484).

PR-#484

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The ApplicationSet sets destination namespace to argocd-infra-instance, and the staging overlay
doesn't set a namespace, while ExternalSecrets have no metadata.namespace and reference the
allowlisted ClusterSecretStore; the store currently only allowlists argocd-infra-deployments, and
past PR #484 documents the same failure mode when namespaces are missing from this allowlist.

argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[22-24]
components/argocd-infra-instance/internal-staging/kustomization.yaml[1-7]
components/argocd-infra-instance/internal-staging/external-secrets/stg-p01-es.yaml[1-21]
components/argocd-infra-instance/internal-staging/patches/argocd-environment-patches.yaml[1-8]
components/cluster-secret-store/base/appsre-stonesoup-vault-secret-store.yaml[28-42]
PR-#484

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new `ExternalSecret` resources use `ClusterSecretStore/appsre-stonesoup-vault`, which is namespace-allowlisted. Currently, the allowlist update only adds `argocd-infra-deployments`, but:
- The ApplicationSet destination namespace is `argocd-infra-instance`.
- The staging overlay does not set a kustomize namespace, so ExternalSecrets have no `metadata.namespace` and will land in the Application's destination namespace.
- The overlay patches indicate intent to deploy into `argocd-infra-deployments-staging` / `argocd-infra-deployments-production`.

## Issue Context
This repo already hit the same class of issue with namespace allowlists blocking ExternalSecrets (see PR #484).

## Fix Focus Areas
- argo-cd-apps/base/internal/argocd-infra-instance/appset.yaml[22-24]
- components/argocd-infra-instance/internal-staging/kustomization.yaml[1-7]
- components/argocd-infra-instance/internal-staging/external-secrets/stg-p01-es.yaml[1-21]
- components/argocd-infra-instance/internal-staging/patches/argocd-environment-patches.yaml[1-8]
- components/argocd-infra-instance/internal-production/patches/argocd-environment-patches.yaml[1-8]
- components/cluster-secret-store/base/appsre-stonesoup-vault-secret-store.yaml[28-42]

## Proposed fix
1) Decide the canonical namespace for this ArgoCD instance per environment (e.g., `argocd-infra-deployments-staging` and `argocd-infra-deployments-production`).
2) Ensure ExternalSecrets are rendered into that namespace (set `namespace:` in the overlay kustomization, or add `metadata.namespace` explicitly).
3) Update the ClusterSecretStore allowlist to include every namespace that will host these ExternalSecrets (e.g., add `argocd-infra-deployments-staging` and `argocd-infra-deployments-production`, and/or `argocd-infra-instance` if you keep that destination).
4) Optionally align the ApplicationSet `destination.namespace` with the chosen namespace to avoid accidental defaulting.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Missing patch file path ✓ Resolved 🐞 Bug ≡ Correctness
Description
Both internal-staging and internal-production overlays reference patches/environment-patches.yaml,
but the only patch file added is patches/argocd-environment-patches.yaml, so kustomize will fail
to load the overlay patches.
Code

components/argocd-infra-instance/internal-production/kustomization.yaml[R9-15]

+patches:
+  - path: patches/environment-patches.yaml
+    target:
+      group: argoproj.io
+      version: v1beta1
+      kind: ArgoCD
+  - path: patches/namespace-environment-patches.yaml
Relevance

⭐⭐⭐ High

Repo history shows fixing broken kustomize resource/paths is accepted to restore sync/build (e.g.,
PR #347).

PR-#347

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The kustomizations reference patches/environment-patches.yaml, but the patch file present in the
overlay is named argocd-environment-patches.yaml, so the referenced path cannot be resolved.

components/argocd-infra-instance/internal-production/kustomization.yaml[9-15]
components/argocd-infra-instance/internal-staging/kustomization.yaml[8-14]
components/argocd-infra-instance/internal-production/patches/argocd-environment-patches.yaml[1-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`components/argocd-infra-instance/internal-{staging,production}/kustomization.yaml` references a patch file that does not exist (`patches/environment-patches.yaml`). This breaks kustomize builds for these overlays.

## Issue Context
The patch files that do exist are named `patches/argocd-environment-patches.yaml`.

## Fix Focus Areas
- components/argocd-infra-instance/internal-production/kustomization.yaml[9-19]
- components/argocd-infra-instance/internal-staging/kustomization.yaml[8-18]

## Proposed fix
Either:
1) Rename `patches/argocd-environment-patches.yaml` to `patches/environment-patches.yaml`, OR
2) Update both kustomization files to reference `patches/argocd-environment-patches.yaml`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. Subscription health nil crash ✓ Resolved 🐞 Bug ☼ Reliability
Description
The Subscription resourceHealthChecks Lua script only initializes numDegraded/numPending/msg
when obj.status.conditions is non-nil, but it later performs numeric comparisons like `numPending
> 0 unconditionally. If a Subscription has status but no status.conditions` yet, the script will
attempt to compare nil to a number and error, preventing correct health computation.
Code

components/argocd-infra-instance/base/argocd.yaml[R166-200]

+    - check: |
+        health_status = {}
+        if obj.status ~= nil then
+            if obj.status.conditions ~= nil then
+                numDegraded = 0
+                numPending = 0
+                msg = ""
+                for i, condition in pairs(obj.status.conditions) do
+                    msg = msg .. i .. ": " .. condition.type .. " | " .. condition.status .. "\n"
+                    if condition.type == "InstallPlanPending" and condition.status == "True" then
+                        numPending = numPending + 1
+                    elseif (condition.type == "InstallPlanMissing" and condition.reason ~= "ReferencedInstallPlanNotFound") then
+                        numDegraded = numDegraded + 1
+                    elseif (condition.type == "CatalogSourcesUnhealthy" or condition.type == "InstallPlanFailed" or condition.type == "ResolutionFailed") and condition.status == "True" then
+                        numDegraded = numDegraded + 1
+                    end
+                end
+            end
+            if numDegraded == 0 and numPending == 0 then
+                health_status.status = "Healthy"
+                health_status.message = msg
+                return health_status
+            elseif numPending > 0 and numDegraded == 0 and obj.spec.installPlanApproval == "Manual" then
+                health_status.status = "Healthy"
+                health_status.message = "An install plan for a subscription is pending installation but install plan approval is set to manual so considering this as healthy: " .. msg
+                return health_status
+            elseif numPending > 0 and numDegraded == 0 then
+                health_status.status = "Progressing"
+                health_status.message = "An install plan for a subscription is pending installation"
+                return health_status
+            else
+                health_status.status = "Degraded"
+                health_status.message = msg
+                return health_status
+            end
Relevance

⭐⭐ Medium

No historical evidence found for Lua health-check nil-comparison crash patterns in this repo’s past
reviews.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The script assigns numDegraded/numPending/msg only inside the if obj.status.conditions ~= nil
block, but later evaluates numPending > 0 and other expressions even when that block didn’t run,
which will error if those variables are nil.

components/argocd-infra-instance/base/argocd.yaml[166-200]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Subscription health check script can throw a Lua runtime error when `obj.status` exists but `obj.status.conditions` is missing/empty: `numPending` and `numDegraded` are left nil and then compared using `>`.

### Issue Context
This breaks health evaluation for Subscriptions during early reconciliation phases (when status/conditions may not be populated yet).

### Fix Focus Areas
- components/argocd-infra-instance/base/argocd.yaml[166-203]

### Suggested fix
At the start of the Subscription check, initialize variables with safe defaults and keep them local:
- `local health_status = {}`
- `local numDegraded = 0`
- `local numPending = 0`
- `local msg = ""`
Then:
- If `obj.status == nil`, return a Progressing/Unknown status.
- If `obj.status.conditions == nil`, skip the loop and rely on the default counters (0), avoiding `nil > 0` comparisons.
This preserves intended behavior while eliminating nil-comparison crashes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Stray token in exclusions ✓ Resolved 🐞 Bug ≡ Correctness
Description
spec.resourceExclusions contains an extra EOT line in the embedded exclusions YAML, making the
exclusions payload invalid and preventing ArgoCD from applying the intended TaskRun/PipelineRun
exclusion rules.
Code

components/argocd-infra-instance/base/argocd.yaml[R127-135]

+  resourceExclusions: |
+    - apiGroups:
+      - tekton.dev
+      clusters:
+      - '*'
+      kinds:
+      - TaskRun
+      - PipelineRun
+    EOT
Relevance

⭐⭐ Medium

No similar historical finding; team usually fixes manifest-breaking issues (see kustomize build
fixes in PR #347).

PR-#347

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The exclusions block includes a literal EOT line after the list items, which is not valid YAML
list content for the embedded exclusions configuration.

components/argocd-infra-instance/base/argocd.yaml[127-135]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`spec.resourceExclusions` is an embedded YAML list expressed as a multi-line string. The current value contains an `EOT` line, which makes the embedded YAML invalid and breaks the exclusions config.

## Fix Focus Areas
- components/argocd-infra-instance/base/argocd.yaml[127-135]

## Proposed fix
Delete the `EOT` line so the block scalar contains only the YAML list of exclusions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. ClusterRole bound wrong instance ✓ Resolved 🐞 Bug ≡ Correctness
Description
The custom-permissions ClusterRole is annotated for ArgoCD instance argocd in namespace argocd,
but the new ArgoCD CR is named/namespaced argocd-infra-deployments, so the role is not associated
with the intended ArgoCD instance configuration.
Code

components/argocd-infra-instance/base/clusterrole.yaml[R10-12]

+  annotations:
+    argocds.argoproj.io/name: argocd
+    argocds.argoproj.io/namespace: argocd
Relevance

⭐⭐ Medium

No direct precedent for ArgoCD instance annotation mismatches; closest RBAC binding/namespace
alignment feedback appeared in PR #326.

PR-#326

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The ClusterRole annotations explicitly reference argocd/argocd while the ArgoCD CR created by this
component is argocd-infra-deployments in argocd-infra-deployments.

components/argocd-infra-instance/base/clusterrole.yaml[9-13]
components/argocd-infra-instance/base/argocd.yaml[1-6]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ClusterRole annotations indicate it belongs to ArgoCD `argocd` in namespace `argocd`, but this component defines an ArgoCD instance `argocd-infra-deployments` in namespace `argocd-infra-deployments`. This mismatch can prevent the role from being picked up/used as intended for that instance.

## Issue Context
This ClusterRole is labeled for aggregation (`argocd/aggregate-to-controller: "true"`) and the ArgoCD CR enables `aggregatedClusterRoles: true`.

## Fix Focus Areas
- components/argocd-infra-instance/base/clusterrole.yaml[9-13]
- components/argocd-infra-instance/base/argocd.yaml[1-8]

## Proposed fix
Update `argocds.argoproj.io/name` and `argocds.argoproj.io/namespace` to match the ArgoCD instance created by this component (and ensure env overlays keep them consistent if the instance name/namespace changes per environment).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

12. internal-production overlay lacks base ✗ Dismissed 📘 Rule violation ⌂ Architecture
Description
components/argocd-infra-instance/internal-production/kustomization.yaml defines an environment
overlay but does not reference the component base/ (it has resources: []), which breaks the
required component overlay layout and can lead to production renders/deploys producing no resources.
Code

components/argocd-infra-instance/internal-production/kustomization.yaml[R1-3]

+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources: [] # Not yet deployed to production
Relevance

⭐⭐⭐ High

Repo production placeholders include minimal resources (namespace) not empty; empty overlays
discouraged in practice.

PR-#384
PR-#369
PR-#386

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1104 requires each environment-specific overlay under components/<name>/ to
contain a kustomization.yaml that references the component base/. The new internal-production
overlay has resources: [], so it does not reference ../base as required.

Rule 1104: Enforce Kustomize component directory layout with base and overlays
components/argocd-infra-instance/internal-production/kustomization.yaml[1-3]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The `internal-production` kustomize overlay exists but does not include `../base` as a resource (`resources: []`). This violates the expected component layout where each environment overlay points to the component base.

## Issue Context
If production is not supported yet, consider removing the overlay directory entirely to avoid consumers expecting it to render resources. If it is supported, it should include `../base` and optionally apply production-specific patches.

## Fix Focus Areas
- components/argocd-infra-instance/internal-production/kustomization.yaml[1-3]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. Unsafe jqPathExpressions selector ✓ Resolved 🐞 Bug ☼ Reliability
Description
The ServiceAccount ignore-differences rule uses the jq iterator .imagePullSecrets[], which errors
when imagePullSecrets is absent/null (a common case). This can prevent the ignore-differences rule
from applying and can surface noisy diffs or jq-evaluation errors during ArgoCD comparisons.
Code

components/argocd-infra-instance/base/argocd.yaml[R92-94]

+    resource.customizations.ignoreDifferences._ServiceAccount:
+        jqPathExpressions:
+          - '.imagePullSecrets[] | select(.name | test("-dockercfg-|-token-"))'
Relevance

⭐⭐ Medium

No prior repo evidence on jqPathExpressions null-safety; reliability fix seems reasonable but
unproven historically.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new ArgoCD config defines a jqPathExpression that iterates imagePullSecrets unconditionally,
but ServiceAccounts in this repo commonly omit that field (so the iterator can fail on null/missing
values).

components/argocd-infra-instance/base/argocd.yaml[92-98]
components/internal-services/internal-staging/rbac/service_account.yaml[1-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The ArgoCD `resource.customizations.ignoreDifferences._ServiceAccount` jq expression iterates over `.imagePullSecrets[]`, which can error when the field is missing.

### Issue Context
Many ServiceAccount objects do not define `imagePullSecrets`, so the expression should tolerate missing/null fields.

### Fix Focus Areas
- components/argocd-infra-instance/base/argocd.yaml[92-94]

### Suggested change
Update the expression to be null-safe, e.g. one of:
- `.imagePullSecrets[]? | select(.name | test("-dockercfg-|-token-"))`
- `(.imagePullSecrets // [])[] | select(.name | test("-dockercfg-|-token-"))`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


14. Crossplane health precedence bug ✓ Resolved 🐞 Bug ≡ Correctness
Description
The Crossplane health.lua condition `obj.status == nil or next(obj.status) == nil and
contains(...) has incorrect operator precedence, so any Crossplane resource with status` missing
is immediately marked Healthy even if its kind is not in the has_no_status allowlist. This can
mask real failures by reporting Healthy too early.
Code

components/argocd-infra-instance/base/argocd.yaml[R50-54]

+            if obj.status == nil or next(obj.status) == nil and contains(has_no_status, obj.kind) then
+                health_status.status = "Healthy"
+                health_status.message = "Resource is up-to-date."
+              return health_status
+            end
Relevance

⭐⭐ Medium

No historical evidence found for Crossplane health.lua operator-precedence bugs in this repo’s
review history.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The health script currently returns Healthy whenever obj.status == nil due to and binding
tighter than or, which is not restricted to the has_no_status kinds.

components/argocd-infra-instance/base/argocd.yaml[41-58]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Crossplane health.lua mixes `or` and `and` without parentheses, changing the intended meaning and incorrectly returning Healthy for any resource with `obj.status == nil`.

### Issue Context
Lua evaluates `and` before `or`, so the current expression is parsed as:
`(obj.status == nil) or ((next(obj.status) == nil) and contains(...))`

### Fix Focus Areas
- components/argocd-infra-instance/base/argocd.yaml[41-58]

### Suggested fix
Rewrite with explicit grouping, e.g.:
`if (obj.status == nil or next(obj.status) == nil) and contains(has_no_status, obj.kind) then ... end`
so only the allowlisted kinds are treated as Healthy when status is absent/empty.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
15. RBAC privileges overly broad ✗ Dismissed 🐞 Bug ⛨ Security
Description
The aggregated ClusterRole grants wildcard (*) permissions on highly sensitive cluster-wide
resources (RBAC bindings, SCCs, Secrets), substantially increasing blast radius if this ArgoCD
instance or any synced workload is compromised.
Code

components/argocd-infra-instance/base/clusterrole.yaml[R205-231]

+    - "rbac.authorization.k8s.io"
+  resources:
+    - clusterroles
+    - clusterrolebindings
+    - roles
+    - rolebindings
+  verbs:
+    - "*"
+- apiGroups:
+    - "route.openshift.io"
+  resources:
+    - routes
+    - routes/custom-host
+  verbs:
+    - "*"
+- apiGroups:
+    - "scheduling.k8s.io"
+  resources:
+    - priorityclasses
+  verbs:
+    - "*"
+- apiGroups:
+    - "security.openshift.io"
+  resources:
+    - securitycontextconstraints
+  verbs:
+    - "*"
Relevance

⭐⭐ Medium

Least-privilege feedback exists but not clearly accepted; repo has widened RBAC with '*' when needed
(e.g., PR #382).

PR-#382
PR-#325
PR-#370

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The ClusterRole explicitly grants * verbs for RBAC objects and SCCs, and also grants * over
secrets and namespaces, which is a high-privilege permission set.

components/argocd-infra-instance/base/clusterrole.yaml[14-26]
components/argocd-infra-instance/base/clusterrole.yaml[205-231]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ArgoCD controller ClusterRole is extremely privileged (wildcard verbs across RBAC, SCC, secrets, namespaces, CRDs, etc.). This should be reviewed and tightened to the minimum set needed for `infra-deployments` management.

## Issue Context
Because this role is aggregated to the ArgoCD controller, it effectively defines what the controller can do cluster-wide.

## Fix Focus Areas
- components/argocd-infra-instance/base/clusterrole.yaml[14-26]
- components/argocd-infra-instance/base/clusterrole.yaml[205-231]

## Proposed fix
Replace `verbs: ['*']` with least-privilege verb/resource sets, and avoid granting SCC/RBAC mutation unless strictly required (e.g., prefer read-only where possible; isolate SCC/RBAC changes to a narrower set of resources/namespaces if feasible).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

16. Duplicate PDB rule ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The new ClusterRole repeats the same policy/poddisruptionbudgets rule twice, which is redundant
and increases maintenance/review overhead without changing effective permissions.
Code

components/argocd-infra-instance/base/clusterrole.yaml[R186-203]

+- apiGroups:
+    - "policy"
+  resources:
+    - poddisruptionbudgets
+  verbs:
+    - "*"
+- apiGroups:
+    - "redhatcop.redhat.io"
+  resources:
+    - groupsyncs
+  verbs:
+    - "*"
+- apiGroups:
+    - "policy"
+  resources:
+    - poddisruptionbudgets
+  verbs:
+    - "*"
Relevance

⭐⭐ Medium

No clear historical evidence on removing duplicate RBAC rules; no close accepted/rejected precedents
found.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The ClusterRole rules list contains two separate entries with the same apiGroup/resource/verbs for
PodDisruptionBudgets.

components/argocd-infra-instance/base/clusterrole.yaml[186-203]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`components/argocd-infra-instance/base/clusterrole.yaml` contains two identical RBAC rules granting `*` on `policy/poddisruptionbudgets`.

### Issue Context
Duplicate RBAC entries don’t change the resulting permissions, but they add noise and can confuse future diffs/audits.

### Fix Focus Areas
- components/argocd-infra-instance/base/clusterrole.yaml[186-203]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


17. ns.yaml should be namespace.yaml 📘 Rule violation ⚙ Maintainability
Description
The new manifest components/argocd-infra-instance/base/ns.yaml declares kind: Namespace, but the
filename base is ns rather than namespace, violating the required Kind-based manifest naming
convention. This breaks the repo rule that manifest filenames must match their single primary
resource Kind.
Code

components/argocd-infra-instance/base/ns.yaml[2]

+kind: Namespace
Relevance

⭐ Low

Repo historically rejects Kind-based filename enforcement; similar rename suggestions rejected in PR
#484.

PR-#484

ⓘ Recommendations generated based on similar findings in past PRs

Ev...

Comment thread components/argocd-infra-instance/internal-production/kustomization.yaml Outdated
Comment thread components/cluster-secret-store/base/appsre-stonesoup-vault-secret-store.yaml Outdated
Comment thread components/argocd-infra-instance/base/clusterrole.yaml Outdated
Comment thread components/argocd-infra-instance/base/argocd.yaml Outdated
Comment thread components/argocd-infra-deployments/base/clusterrole.yaml
Comment thread components/argocd-infra-instance/base/clusterrole.yaml Outdated
@qodo-for-redhat-appstudio

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3b01561

@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch from 3b01561 to 9c52c72 Compare July 2, 2026 17:05
@enkeefe00

Copy link
Copy Markdown
Collaborator Author

/agentic_review

Comment thread argo-cd-apps/base/internal/argocd-infra-deployments/appset.yaml
Comment thread argo-cd-apps/base/internal/argocd-infra-deployments/appset.yaml
Comment thread components/argocd-infra-instance/base/argocd.yaml Outdated
Comment thread components/argocd-infra-instance/base/argocd.yaml Outdated
@qodo-for-redhat-appstudio

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 9c52c72

@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch from 9c52c72 to fcc3132 Compare July 2, 2026 17:48
@enkeefe00

Copy link
Copy Markdown
Collaborator Author

/agentic_review

Comment thread components/argocd-infra-instance/base/argocd.yaml Outdated
@qodo-for-redhat-appstudio

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit fcc3132

@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch from fcc3132 to 0969f42 Compare July 2, 2026 18:02
@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch 2 times, most recently from ed80f8d to a494b81 Compare July 2, 2026 18:30
@enkeefe00

Copy link
Copy Markdown
Collaborator Author

/agentic_review

@qodo-for-redhat-appstudio

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit a494b81

@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch from a494b81 to dabc830 Compare July 2, 2026 18:48
@enkeefe00

Copy link
Copy Markdown
Collaborator Author

/agentic_review

@qodo-for-redhat-appstudio

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit dabc830

@openshift-ci-robot

openshift-ci-robot commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

@enkeefe00: This pull request references KFLUXINFRA-4167 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Use GitOps to deploy a staging ArgoCD instance for infra-deployments

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@enkeefe00 enkeefe00 changed the title KFLUXINFRA-4167: Create an ArgoCD instance for infra-deployments KFLUXINFRA-4167: Create a staging ArgoCD instance for infra-deployments Jul 2, 2026
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: argocd-infra-deployments-instance

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious, why adding the word "instance"? if we feel that this is needed, then everything should be name -instance, like internal-services-instance, kargo-instance and so on.

If you have good argument for keeping it, we can but I would like to understand. I would personally name the applicationSet just "argocd-infra-deployments"

generators:
- clusters:
values:
sourceRoot: components/argocd-infra-instance

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we usually name the ApplicationSet, component folder and namespace the same. We should follow this here too so depending on the applicationSet we agree above, I think this component folder should be renamed too, to what ever name we agree above.

repoURL: https://github.com/redhat-appstudio/infra-common-deployments.git
targetRevision: main
destination:
namespace: argocd-infra-instance

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we usually name the ApplicationSet, component folder and namespace the same. We should follow this here too so depending on the applicationSet we agree above, I think this namespace should be renamed too, to what ever name we agree above.

@@ -0,0 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: argocd-infra-deployments-staging

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused here, we use yet another NS than the target one from applicationSet?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the applicationSet to name the namespace using the environment variable.

@@ -0,0 +1,266 @@
apiVersion: argoproj.io/v1beta1
kind: ArgoCD

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where did check to get this CR populated, I see difference between this one and the one we use in app-interface to create the our staging ArgoCD

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally used what we were using in the ArgoCD Terraform module. I updated it to what I found in app-interface.

- extract:
conversionStrategy: Default
decodingStrategy: None
key: staging/infrastructure/github-argocd/kflux-c-stg-i01/redhat-appstudio

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here, we should not reuse a repo secret from another cluster, we should have one for this ArgoCD. We have 3 options, use the one from existing internal Argo, use the existing one from external Argo, or create another one for this instance and eventually that will be the only one left once we pull the plug on 2 former ArgoCD.

I vote for option 3 so create secret in vault with this path and use it: stonesoup/staging/platform/github-argocd/argocd-infra-deployments (again, we want to name this base on applicationSet/Application/NS/component so better sort out the naming so we stay consistent)

@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch from dabc830 to 41f5685 Compare July 2, 2026 22:14
Use GitOps to deploy ArgoCD instances for infra-deployments

KFLUXINFRA-4167
@enkeefe00 enkeefe00 force-pushed the create-infra-deployments-argocds branch from 41f5685 to 455a49d Compare July 2, 2026 22:19
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argocd-infra-deployments-custom-permissions

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need that? This argoCD will create resource in a remote cluster using the permission allowed to the serviceAccount used by argo, specified in the k8s secret.

labels:
app.kubernetes.io/name: argocd-infra-deployments-staging
app.kubernetes.io/part-of: konflux-common
app.kubernetes.io/instance: argocd-infra-deployments-staging

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need those 3 labels?

repoURL: https://github.com/redhat-appstudio/infra-common-deployments.git
targetRevision: main
destination:
namespace: argocd-infra-deployments-{{values.environment}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will end up being "argocd-infra-deployments-internal-staging" and not "argocd-infra-deployments-staging" as expected in the rest of this PR.

If you want the suffix staging in the NS name, you will need to use go templating like we did in k8s-groups applicationSet

spec:
goTemplate: true
....
and then this would be:
argocd-infra-deployments-{{trimPrefix "external-" (trimPrefix "internal-" .values.environment)}}

Question, we will have one argocd on common staging cluster for the staging konflux clusters and one on common production cluster for the production konflux clusters, another option is just use argocd-infra-deployments as NS as there will no t be any conflict.

p, role:release-eng, applications, get, rh-managed-workspaces-config/*, allow
p, role:release-eng, logs, get, rh-managed-workspaces-config/*, allow

g, argocd-release-eng, role:release-eng

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to highlight that this will not work. Here we configure argocd permission and map them to the k8s groups "argocd-developers" and "argocd-release-eng". Those 2 groups exist on appsre cluster, created by some yaml in app-interface but they do not in the common cluster.

First, we do not need the tenants-config and releng permissions, this is a left over from when we had single argocd instance deploying both tenant and konflux itself.

For the developer role, that we still need, we could probably do like we did in the local arogcd, i.e. bind all the konflux-* groups to the dev people:

        p, role:konflux-argocd-devs, applications, get, */*, allow
        p, role:konflux-argocd-devs, applications, sync, */*, allow
        p, role:konflux-argocd-devs, logs, get, */*, allow
        g, konflux-admins, role:konflux-argocd-devs
        g, konflux-build, role:konflux-argocd-devs
        g, konflux-contributors, role:konflux-argocd-devs
        g, konflux-devprod, role:konflux-argocd-devs
        g, konflux-ec, role:konflux-argocd-devs
        g, konflux-infra, role:konflux-argocd-devs
        g, konflux-integration, role:konflux-argocd-devs
        g, konflux-kubearchive, role:konflux-argocd-devs
        g, konflux-migration, role:konflux-argocd-devs
        g, konflux-mintmaker-team, role:konflux-argocd-devs
        g, konflux-o11y, role:konflux-argocd-devs
        g, konflux-qe, role:konflux-argocd-devs
        g, konflux-release-team, role:konflux-argocd-devs
        g, konflux-support-ops, role:konflux-argocd-devs
        g, konflux-ui, role:konflux-argocd-devs
        g, konflux-vanguard, role:konflux-argocd-devs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants